﻿using EasyIot.Common;
using DotNetty.Buffers;
using DotNetty.Common.Utilities;
using DotNetty.Handlers.Timeout;
using DotNetty.Transport.Channels;
using System;
using DotNettyExtensions.entity;

namespace DotNettyExtensions.handler
{
    public class TCPHandler : ChannelHandlerAdapter
    {
        IProtocolHandler protocol;

        public TCPHandler(IProtocolHandler protocol)
        {
            this.protocol = protocol;
        }

        public override void ChannelActive(IChannelHandlerContext ctx)
        {
            ServerMgr.AddClient(ctx, System.Net.Sockets.ProtocolType.Tcp, ctx.Channel.RemoteAddress);

            Logger.Info("tcp客户端已经连接,client:" + ServerMgr.GetSN(ctx.Channel.RemoteAddress));
        }

        public override void ChannelRead(IChannelHandlerContext ctx, object message)
        {
            ServerMgr.GetClient(ctx).LastTime = CommonUtility.GetNowTimestamp();
            protocol.ChannelRead(ctx, ctx.Channel.RemoteAddress, message);
        }

        public override void ChannelReadComplete(IChannelHandlerContext ctx)
        {
            ctx.Flush();
        }

        public override void ChannelInactive(IChannelHandlerContext ctx)
        {
            ServerMgr.RemoveClient(ctx, "ChannelInactive");
        }

        public override void ExceptionCaught(IChannelHandlerContext ctx, Exception exception)
        {
            ServerMgr.RemoveClient(ctx, "exceptionCaught");
        }

        public override void UserEventTriggered(IChannelHandlerContext ctx, object evt)
        {
            if (evt is IdleStateEvent)
            {
                string type = "未知";
                IdleStateEvent event1 = (IdleStateEvent)evt;
                switch (event1.State)
                {
                    case IdleState.ReaderIdle: type = "read idle"; break;
                    case IdleState.WriterIdle: type = "write idle"; break;
                    case IdleState.AllIdle: type = "all idle"; break;
                    default: break;
                }
                ServerMgr.RemoveClient(ctx, "超时退出(" + type + ")");
            }
            else
            {
                base.UserEventTriggered(ctx, evt);
            }
        } 
    }
}